{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Extracting MNIST_data\\train-images-idx3-ubyte.gz\n",
      "Extracting MNIST_data\\train-labels-idx1-ubyte.gz\n",
      "Extracting MNIST_data\\t10k-images-idx3-ubyte.gz\n",
      "Extracting MNIST_data\\t10k-labels-idx1-ubyte.gz\n",
      "testData.shape: (50, 784)\n",
      "trainData.shape: (500, 784)\n",
      "testLabel= [[0. 0. 0. 0. 0. 0. 1. 0. 0. 0.]\n",
      " [0. 0. 0. 0. 0. 1. 0. 0. 0. 0.]\n",
      " [0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]\n",
      " [0. 0. 1. 0. 0. 0. 0. 0. 0. 0.]\n",
      " [0. 0. 0. 0. 0. 0. 0. 0. 1. 0.]\n",
      " [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]\n",
      " [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]\n",
      " [0. 0. 1. 0. 0. 0. 0. 0. 0. 0.]\n",
      " [0. 0. 0. 0. 0. 0. 1. 0. 0. 0.]\n",
      " [0. 0. 0. 0. 0. 0. 0. 0. 1. 0.]\n",
      " [1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n",
      " [0. 0. 0. 0. 0. 1. 0. 0. 0. 0.]\n",
      " [0. 0. 0. 0. 0. 0. 1. 0. 0. 0.]\n",
      " [0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]\n",
      " [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]\n",
      " [1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]\n",
      " [0. 0. 0. 0. 0. 0. 1. 0. 0. 0.]\n",
      " [0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]\n",
      " [0. 0. 0. 0. 0. 0. 1. 0. 0. 0.]\n",
      " [0. 0. 0. 0. 0. 0. 1. 0. 0. 0.]\n",
      " [0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]\n",
      " [0. 0. 0. 0. 0. 0. 1. 0. 0. 0.]\n",
      " [0. 0. 0. 0. 0. 0. 0. 1. 0. 0.]\n",
      " [0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]\n",
      " [0. 0. 0. 0. 0. 0. 0. 1. 0. 0.]\n",
      " [0. 0. 1. 0. 0. 0. 0. 0. 0. 0.]\n",
      " [0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]\n",
      " [0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]\n",
      " [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]\n",
      " [0. 0. 0. 0. 0. 0. 0. 0. 1. 0.]\n",
      " [0. 0. 0. 0. 0. 0. 0. 1. 0. 0.]\n",
      " [0. 0. 0. 0. 0. 0. 1. 0. 0. 0.]\n",
      " [0. 0. 0. 0. 0. 0. 0. 1. 0. 0.]\n",
      " [0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]\n",
      " [0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]\n",
      " [0. 0. 0. 0. 0. 0. 0. 0. 1. 0.]\n",
      " [0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]\n",
      " [0. 0. 0. 1. 0. 0. 0. 0. 0. 0.]\n",
      " [0. 0. 1. 0. 0. 0. 0. 0. 0. 0.]\n",
      " [0. 0. 0. 0. 0. 1. 0. 0. 0. 0.]\n",
      " [0. 0. 0. 0. 0. 0. 1. 0. 0. 0.]\n",
      " [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]\n",
      " [0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]\n",
      " [0. 0. 0. 1. 0. 0. 0. 0. 0. 0.]\n",
      " [0. 0. 0. 0. 0. 1. 0. 0. 0. 0.]\n",
      " [0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]\n",
      " [0. 0. 0. 0. 0. 0. 0. 0. 1. 0.]\n",
      " [0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]\n",
      " [0. 0. 0. 0. 0. 0. 0. 0. 1. 0.]\n",
      " [0. 0. 1. 0. 0. 0. 0. 0. 0. 0.]]\n",
      "[[[0. 0. 0. ... 0. 0. 0.]\n",
      "  [0. 0. 0. ... 0. 0. 0.]\n",
      "  [0. 0. 0. ... 0. 0. 0.]\n",
      "  [0. 0. 0. ... 0. 0. 0.]]\n",
      "\n",
      " [[0. 0. 0. ... 0. 0. 0.]\n",
      "  [0. 0. 0. ... 1. 0. 0.]\n",
      "  [0. 0. 0. ... 0. 0. 0.]\n",
      "  [0. 0. 0. ... 1. 0. 0.]]\n",
      "\n",
      " [[0. 0. 0. ... 0. 0. 1.]\n",
      "  [0. 0. 0. ... 0. 0. 1.]\n",
      "  [0. 0. 0. ... 0. 0. 1.]\n",
      "  [0. 0. 0. ... 0. 0. 0.]]\n",
      "\n",
      " ...\n",
      "\n",
      " [[0. 0. 0. ... 0. 0. 1.]\n",
      "  [0. 0. 0. ... 0. 0. 1.]\n",
      "  [0. 1. 0. ... 0. 0. 0.]\n",
      "  [0. 0. 0. ... 0. 0. 0.]]\n",
      "\n",
      " [[0. 0. 0. ... 0. 0. 1.]\n",
      "  [0. 0. 0. ... 1. 0. 0.]\n",
      "  [0. 0. 0. ... 0. 0. 1.]\n",
      "  [0. 0. 0. ... 0. 0. 1.]]\n",
      "\n",
      " [[0. 0. 1. ... 0. 0. 0.]\n",
      "  [0. 0. 0. ... 1. 0. 0.]\n",
      "  [0. 0. 1. ... 0. 0. 0.]\n",
      "  [0. 0. 1. ... 0. 0. 0.]]] (50, 4, 10)\n",
      "[6 7 9 2 8 1 1 1 6 8 0 5 6 4 1 0 6 4 6 6 4 6 7 9 7 2 1 9 1 5 7 6 7 9 9 0 4\n",
      " 3 2 5 6 1 9 3 0 1 8 9 9 2]\n",
      "[6 5 9 2 8 1 1 2 6 8 0 5 6 4 1 0 6 4 6 6 4 6 7 9 7 2 4 9 1 8 7 6 7 9 9 8 4\n",
      " 3 2 5 6 1 9 3 5 1 8 9 8 2]\n",
      "正确率 0.86\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import tensorflow as tf\n",
    "import random\n",
    "from tensorflow.examples.tutorials.mnist import input_data\n",
    "\n",
    "# 1.准备数据 参数1：文件路径 参数2：oneHot 数组内有一个内容为1则其他全为0\n",
    "mnist = input_data.read_data_sets('MNIST_data',one_hot=True)\n",
    "# 属性设置\n",
    "trainNum = 55000\n",
    "testNum = 10000\n",
    "trainSize = 500\n",
    "testSize = 50\n",
    "# 数据分解 \n",
    "# 从一个给定的一维数组中生成一个随机样本 参数1：采样范围 参数2：采样个数 参数3：是否允许重复\n",
    "trainIndex = np.random.choice(trainNum,trainSize,replace=False)\n",
    "testIndex = np.random.choice(testNum,testSize,replace=False)\n",
    "# 获取训练图片和标签\n",
    "trainData = mnist.train.images[trainIndex]\n",
    "trainLabel = mnist.train.labels[trainIndex]\n",
    "# 获取测试数据和标签\n",
    "testData = mnist.test.images[testIndex]\n",
    "testLabel = mnist.test.labels[testIndex]\n",
    "# 图像大小为28*28=784\n",
    "print('testData.shape:',testData.shape)\n",
    "print('trainData.shape:',trainData.shape)\n",
    "# 1对应的下标表示数字的值\n",
    "print('testLabel=',testLabel)\n",
    "# 数据输入 n*784(28*28=784)\n",
    "trainDataInput = tf.placeholder(shape=[None,784],dtype=tf.float32)\n",
    "testDataInput = tf.placeholder(shape=[None,784],dtype=tf.float32)\n",
    "# 标签：10个下标对应10个数字 n*10 n代表数据量\n",
    "trainLabelInput = tf.placeholder(shape=[None,10],dtype=tf.float32)\n",
    "testLabelInput = tf.placeholder(shape=[None,10],dtype=tf.float32)\n",
    "\n",
    "# 2.knn模型\n",
    "# knn中测试图片与训练图片的距离差值（每个像素差异总和）计算\n",
    "# 转换维度 增加1维表示距离 5*784 -> 5*1*784\n",
    "f1 = tf.expand_dims(testDataInput,1)\n",
    "# 计算距离 1.各维度相减 2.将第2个维度取绝对值以后累加同时降维\n",
    "f2 = tf.subtract(trainDataInput,f1)\n",
    "f3 = tf.reduce_sum(tf.abs(f2),reduction_indices=2)\n",
    "# 取反\n",
    "f4 = tf.negative(f3)\n",
    "# 根据计算结果找到4（k）个最近的图片,得到f4中最大的4个值，因为取反操作也就是f3中最大的值\n",
    "# f6返回图像对应的下标 f5返回差异值\n",
    "f5,f6 = tf.nn.top_k(f4,k=4)\n",
    "# 获取最邻近图片的标签 根据下标索引标签\n",
    "f7 = tf.gather(trainLabelInput,f6)\n",
    "# 将相应的标签转化为对应的数字\n",
    "f8 = tf.reduce_sum(f7,reduction_indices=1)\n",
    "f9 = tf.arg_max(f8,dimension=1)\n",
    "with tf.Session() as sess:\n",
    "    op1 = sess.run(f1,feed_dict={testDataInput:testData[0:testSize]})\n",
    "#   print(op1.shape)\n",
    "#   print(sess.run(f1,feed_dict={testDataInput:testData[0:5]}))\n",
    "#   print(sess.run(f2,feed_dict={testDataInput:testData[0:5],trainDataInput:trainData[0:500]}))\n",
    "    op2 = sess.run(f2,feed_dict={testDataInput:testData[0:testSize],trainDataInput:trainData[0:trainSize]})\n",
    "#   print(op2.shape)\n",
    "    op3 = sess.run(f3,feed_dict={testDataInput:testData[0:testSize],trainDataInput:trainData[0:trainSize]})\n",
    "#   print(sess.run(f3,feed_dict={testDataInput:testData[0:5],trainDataInput:trainData[0:500]}))\n",
    "#   print(op3.shape)\n",
    "    op4 = sess.run(f4,feed_dict={testDataInput:testData[0:testSize],trainDataInput:trainData[0:trainSize]})\n",
    "#   print(op4[0,0],op4.shape)\n",
    "    op5,op6 = sess.run((f5,f6),feed_dict={testDataInput:testData[0:testSize],trainDataInput:trainData[0:trainSize]})\n",
    "#   print(op5,op5.shape,op6,op6.shape)\n",
    "    op7 = sess.run(f7,feed_dict={testDataInput:testData[0:testSize],trainDataInput:trainData[0:trainSize],trainLabelInput:trainLabel})\n",
    "    print(op7,op7.shape)\n",
    "    op8 = sess.run(f8,feed_dict={testDataInput:testData[0:testSize],trainDataInput:trainData[0:trainSize],trainLabelInput:trainLabel})\n",
    "    op9 = sess.run(f9,feed_dict={testDataInput:testData[0:testSize],trainDataInput:trainData[0:trainSize],trainLabelInput:trainLabel})\n",
    "    print(op9)\n",
    "    # 将预测内容与真值对比\n",
    "    op10 = np.argmax(testLabel[0:testSize],axis=1)\n",
    "    print(op10)\n",
    "# 判断正确率\n",
    "j = 0\n",
    "for i in range(0,testSize):\n",
    "    if op10[i] == op9[i]:\n",
    "        j = j + 1\n",
    "p = j/testSize\n",
    "print('正确率',p)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.4"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
